/*
 * p3608.cpp
 *
 *  Created on: 2013-3-17
 *      Author: zy
 */


#include<algorithm>
#include<cstdio>
#include<cmath>
#include<iostream>
using namespace std;

int sig(double d) {
	return fabs(d) < 1E-6 ? 0 : d < 0 ? -1 : 1;
}
struct Point{
	double x, y;
	double k;
	Point(){}
	Point(double x, double y): x(x), y(y) {}
	void set(double x, double y) {
		this->x = x;
		this->y = y;
	}
	double mod(){//模
		return sqrt(x*x+y*y);
	}
	double mod_pow(){//模的平方
		return x*x + y*y;
	}
	void output() {
		printf("x = %f, y = %f\n", x, y);
	}
	bool operator < (const Point &p) const {
		return sig(x-p.x) != 0 ? x < p.x : sig(y-p.y) < 0;
	}
};

double cross(Point o, Point a, Point b) {
	return (a.x - o.x)*(b.y - o.y)-(b.x - o.x)*(a.y - o.y);
}
double dot(Point &o, Point &a, Point &b) {
	return (a.x-o.x)*(b.x-o.x) + (a.y-o.y)*(b.y-o.y);
}
int btw(Point &x, Point &a, Point &b) {
	return sig(dot(x, a, b));
}
int g_cmp(const void *a, const void *b) {
	int d = sig(((Point*)a)->y-((Point*)b)->y);
	return d ? d : sig(((Point*)a)->x-((Point*)b)->x);
}
//按x从小到大排序，向右走为合法
int graham(Point*p, int n, int*ch)
{
	#define push(x)     ch[len ++]=x
	#define pop()		len --
	sort(p, p+n);
	int len = 0, len0 = 1, i;
	for(i = 0; i < n; i ++)
	{
		while(len > len0 && sig(cross(p[ch[len-1]], p[ch[len-2]], p[i]))<=0)
			pop();
		push(i);
	}
	len0 = len;
	for(i = n-2; i >= 0; i --) {
		while(len > len0 && sig(cross(p[ch[len-1]], p[ch[len-2]], p[i]))<=0)
			pop();
		push(i);
	}
	return len-1;
}

/**
	凸包: jarvis步进法
	------------------
	p: 原始的点
	n: 点的个数
	ch:存储凸包的点（回路，首位相接）

	与graham不同，不会改变p的位置
*/
int jarvis(Point *p, int n, int *ch)
{
	static int d, i, o, s, l, t;
	for(d = i = 0; i < n; i ++)
		if(p[i] < p[d])
			d = i;
	l = s = *ch = d;
	d =1;
	do {
		o = l;
		for(i = 0; i < n; i ++)
			if((t=sig(cross(p[o], p[l], p[i])))>0
|| (t==0 && btw(p[l], p[o], p[i])<=0))
				l = i;
		ch[d ++] = l;
	} while(l != s);
	return d-1;
}
/*
 * 多边形有向面积，逆时针输入为正！
 */
double area(Point * p, int n) {
	double res = 0;
	p[n] = p[0];
	for(int i = 0; i < n; i ++) {
		res += p[i].x*p[i+1].y - p[i+1].x*p[i].y;
	}
	return res / 2;
}
double dis(Point a, Point b) {
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
/**
 * 求凸多边形直径！注意传入凸多边形！
 */
double diam(Point *p, int n) {
	if(area(p, n)<0)	reverse(p, p+n);
	p[n] = p[0];
	double res = 0;
	for(int i = 0, j = 1; i < n; i ++) {
		while(sig(cross(p[i], p[i+1], p[j])-cross(p[i], p[i+1], p[(j+1)%n])) < 0)
			j = (j+1)%n;
		res = max(res, dis(p[i], p[j]));
		res = max(res, dis(p[i+1], p[j]));
	}
	return res;
}


//计算两个凸多边形间最近，最远距离，assume两个凸多边形分离
//返回o到线段ab的最短距离
double minDis(Point o, Point a, Point b) {
	if(sig(dot(b, a, o))<0)	return dis(o, b);
	if(sig(dot(a, b, o))<0)	return dis(o, a);
	return fabs(cross(o, a, b)/dis(a, b));
}
//计算从curAng逆时针转到ab的角
double calRotate(Point a, Point b, double curAng) {
	double x = fmod(atan2(b.y-a.y, b.x-a.x)-curAng, M_PI*2);
	if(x<0)			x += M_PI*2;
	if(x>1.9*M_PI)	x = 0;		//in case x is nearly 2*M_PI
	if(x >= 1.01*M_PI)	while(1);
	return x;
}
//求凸多边形间最小距离，断言P和Q分离
//传入P、Q：凸多边形。n、m：P和Q的顶点个数
//如果P和Q非逆时针，则reverse!
//题目：POJ-3608
//教程：http://blog.csdn.net/ACMaker/archive/2008/壹0/29/3壹78696.aspx
double mind2p(Point *P, int n, Point *Q, int m) {
	if(area(P, n) < 0)	reverse(P, P+n);	//需要逆时针的
	if(area(Q, m) < 0)	reverse(Q, Q+m);
	int p0 = min_element(P, P+n)-P, q0 = max_element(Q, Q+m)-Q;

	double res = dis(P[p0], Q[q0]);

	double ang = -M_PI/2, rotateP, rotateQ;
	int pi, pj, qi, qj, totP, totQ, val;
	for(pi=p0, qi=q0, totP=0, totQ=0; totP<n && totQ<m; ) {
		pj = (pi+1) % n;
		qj = (qi+1) % m;

		rotateP = calRotate(P[pi], P[pj], ang);
		rotateQ = calRotate(Q[qi], Q[qj], ang+M_PI);

		val = sig(rotateP - rotateQ);
		ang += min(rotateP, rotateQ);

		if(val == -1)	res = min(res, minDis(Q[qi], P[pi], P[pj]));
		else if(val==1)	res = min(res, minDis(P[pi], Q[qi], Q[qj]));
		else {
			res = min(res, minDis(P[pi], Q[qi], Q[qj]));
			res = min(res, minDis(P[pj], Q[qi], Q[qj]));
			res = min(res, minDis(Q[qi], P[pi], P[pj]));
			res = min(res, minDis(Q[qj], P[pi], P[pj]));
		}
		if(val != 1)	pi=pj, totP ++;
		if(val != -1)	qi=qj, totQ ++;
	}
	return res;
}
//求凸多边形间最大距离，断言P和Q分离
//传入P、Q：凸多边形。n、m：P和Q的顶点个数
//如果P和Q非逆时针，则reverse!
//教程：http://blog.csdn.net/ACMaker/archive/2008/壹0/29/3壹78794.aspx
double maxd2p(Point *P, int n, Point *Q, int m) {	//【【【待测】】】.......!!!
	if(area(P, n) < 0)	reverse(P, P+n);	//需要逆时针的
	if(area(Q, m) < 0)	reverse(Q, Q+m);
	int p0 = min_element(P, P+n)-P, q0 = max_element(Q, Q+m)-Q;

	double res = dis(P[p0], Q[q0]);

	double ang = -M_PI/2, rotateP, rotateQ;
	int pi, pj, qi, qj, totP, totQ, val;
	for(pi=p0, qi=q0, totP=0, totQ=0; totP<n && totQ<m; ) {
		pj = (pi+1) % n;
		qj = (qi+1) % m;

		rotateP = calRotate(P[pi], P[pj], ang);
		rotateQ = calRotate(Q[qi], Q[qj], ang+M_PI);

		val = sig(rotateP - rotateQ);
		ang += min(rotateP, rotateQ);

		if(val == -1)	res = max(res, max(dis(Q[qi], P[pi]), dis(Q[qi], P[pj])));
		else if(val==1)	res = max(res, max(dis(P[pi], Q[qi]), dis(P[pi], Q[qj])));
		else {
			res = max(res, dis(P[pi], Q[qi]));
			res = max(res, dis(P[pi], Q[qj]));
			res = max(res, dis(P[pj], Q[qi]));
			res = max(res, dis(P[pj], Q[qj]));
		}
		if(val != 1)	pi=pj, totP ++;
		if(val != -1)	qi=qj, totQ ++;
	}
	return res;
}
const int maxn=10010;
Point P[maxn], Q[maxn];
int n, m;
int main()
{
	while(scanf("%d%d", &n, &m), n||m)
	{
		for(int i = 0; i < n; i ++)	scanf("%lf%lf", &P[i].x, &P[i].y);
		for(int i = 0; i < m; i ++)	scanf("%lf%lf", &Q[i].x, &Q[i].y);
		printf("%.5f\n", mind2p(P, n, Q, m));
	}
	return 0;
}

